<template>
  <div>
    <el-form ref="form" :model="form" :rules="rules">
      <el-form-item label="数据库类型" prop="dbType">
        <el-radio v-model="form.dbType" label="mysql" size="large"
          >mySql</el-radio
        >
        <el-radio v-model="form.dbType" label="mssql" size="large" disabled
          >msSql</el-radio
        >
        <el-radio v-model="form.dbType" label="sqlite" size="large" disabled
          >sqlite</el-radio
        >
        <el-radio v-model="form.dbType" label="redis" size="large" disabled
          >redis</el-radio
        >
      </el-form-item>
      <el-form-item label="选择数据库" prop="label">
        <el-col :span="4">
          <el-select
            v-model="form.connSourceTag"
            @change="checkSourceTag"
            placeholder="请选择源链接"
          >
            <el-option
              v-for="item in this.dbs.data"
              :key="item.id"
              :label="item.label"
              :value="item.id"
            >
            </el-option>
          </el-select>
        </el-col>
        <el-col :span="4">
          <el-select v-model="form.checkDbSource" placeholder="请选择源数据库">
            <el-option
              v-for="item in form.sourceDbs"
              :key="item.Database"
              :label="item.Database"
              :value="item.Database"
            >
            </el-option>
          </el-select>
        </el-col>
        <el-col class="line" :span="2">=></el-col>
        <el-col :span="4">
          <el-select
            v-model="form.connTargetTag"
            @change="checkTargetTag"
            placeholder="请选择目标链接"
          >
            <el-option
              v-for="item in this.dbs.data"
              :key="item.id"
              :label="item.label"
              :value="item.id"
            >
            </el-option>
          </el-select>
        </el-col>
        <el-col :span="4">
          <el-select
            v-model="form.checkDbTarget"
            placeholder="请选择目标数据库"
          >
            <el-option
              v-for="item in form.targetDbs"
              :key="item.Database"
              :label="item.Database"
              :value="item.Database"
            >
            </el-option>
          </el-select>
        </el-col>
      </el-form-item>

      <el-form-item label="对比结果（sql）" prop="label">
        <!-- <el-input
          type="textarea"
          :rows="13"
          v-model="form.sqlText"
          placeholder="对比后结果将呈现在此！"
        ></el-input> -->

        <!-- 
        <textarea class="el-textarea__inner"
          :rows="13"
         v-model.lazy="form.sqlText"
          placeholder="对比后结果将呈现在此！"></textarea> -->

        <div
          class="el-textarea__inner"
          style="height: 300px; overflow-y: auto"
          v-html="form.sqlTextShow"
        ></div>
      </el-form-item>

      自动同步功能暂在开发中，请复制您需要同步的差异sql，到数据库中执行
      <!-- <el-form-item
        label="以上内容确认无误，请输入'确认无误'后点击同步"
        prop="label"
      >
        <el-input
          type="text"
          :rows="20"
          placeholder="数据无价，请输入'确认无误'以同意执行！"
        ></el-input>
      </el-form-item> -->
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="closepop">取 消</el-button>
      <el-button type="primary" @click="diffDb">对 比</el-button>
      <!-- <el-button type="primary">同 步</el-button> -->
    </div>
  </div>
</template>
<style lang="stylus">
.page_container {
  // background: red;
  height: 100%;

  &>.el-header {
    line-height: 60px;
    background: #3c3c3c;
  }

  .page-el-aside {
    background: #ddd;
  }
}
</style>
<script>
// var mysql = require("mysql"); //引入mysql模块

// var connection = mysql.createConnection({      //创建mysql实例
//     port:'3306',
//     host     : 'localhost',
//     user     : 'r666t',
//     password : 'shi666',
//     database : 'test666'
// });
import transaction from "@/assets/js/transaction";
import schema from "@/assets/js/schema";
// import util from "@/assets/js/utils";
import { format } from "sql-formatter";

import util from "util";

export default {
  name: "diffStructure",
  props: {
    connFormVisible: {
      type: Boolean,
      default: false,
    },
    checkMenuItemId: {
      default: 0,
    },
  },
  data() {
    return {
      form: {
        checkDbSource: "",
        checkDbTarget: "",

        connSourceTag: "",
        connTargetTag: "",

        connSourceTagConf: {},
        connTargetTagConf: {},

        sourceDbs: {},
        targetDbs: {},
        connSource: "",
        connTarget: "",
        dbType: "mysql",
        sqlText: "",
        sqlTextShow: "",
      },
      dbs: [],
      rules: {
        dbType: [
          { required: true, message: "请选择数据库类型", trigger: "blur" },
        ],
      },
    };
  },

  async created() {
    // this.dbs = this.$utools.db.get("connObject") || false;
    this.dbs = this.$utools.db.get("connObject") || false;
    console.log(this.dbs);
    mysql = this.$mysql;

    this.conn();
  },
  mounted() {},

  methods: {
    closepop() {
      this.$emit("closeStructureContrast");
    },
    checkSourceTag(node) {
      let that = this;
      let connTargetTagConf = "";
      let data = this.dbs.data;

      data.forEach((conn, ci) => {
        if (conn.id == node) {
          connTargetTagConf = conn;
        }
      });
      this.form.sourceDbs = {};
      this.form.checkDbSource = "";
      this.conn(1, connTargetTagConf);
    },
    checkTargetTag(node) {
      let that = this;
      let connTargetTagConf = "";
      let data = this.dbs.data;
      console.log(node);
      data.forEach((conn, ci) => {
        if (conn.id == node) {
          connTargetTagConf = conn;
        }
      });
      this.form.targetDbs = {};
      this.form.checkDbTarget = "";

      this.conn(2, connTargetTagConf);
    },
    conn(type = 0, config = {}) {
      if (type == 0) {
        return;
      }
      // 创建 一个mysql 连接池
      let pool = mysql.createPool({
        port: config.dbPort,
        host: config.dbHost,
        user: config.dbUserName,
        password: config.dbPassword,
        // database: "test666",
        multipleStatements: true,
      });

      var sqls = ["show databases"];
      var params = [
        [1], // parmas 是数组格式 与sqls里的sql语句里 ? 一一对应
      ];

      transaction
        .transaction(pool, sqls, params)
        .then((arrResult) => {
          console.log(arrResult);

          if (type == 1) {
            this.form.connSourceTagConf = {
              port: config.dbPort,
              host: config.dbHost,
              user: config.dbUserName,
              password: config.dbPassword,
              database: "test666",
              multipleStatements: true,
            };

            this.form.connSource = pool;

            this.form.sourceDbs = arrResult[0];
          }
          if (type == 2) {
            this.form.connTargetTagConf = {
              port: config.dbPort,
              host: config.dbHost,
              user: config.dbUserName,
              password: config.dbPassword,
              database: "test666",
              multipleStatements: true,
            };
            this.form.connTarget = pool;
            this.form.targetDbs = arrResult[0];
          }

          // do anything ....
        })
        .catch((err) => {
          // error

          this.form.connSource = {};
          this.form.connTarget = {};

          this.$message.error(err);
          console.log(err);
        });
    },
    diffDb() {
      let that = this;
      if (
        this.form.connSource == "" ||
        this.form.connTarget == "" ||
        this.form.checkDbSource == "" ||
        this.form.checkDbTarget == ""
      ) {
        return;
      }

      this.form.connSourceTagConf.database = this.form.checkDbSource;
      this.form.connTargetTagConf.database = this.form.checkDbTarget;
      let conn_config = {
        source: this.form.connSourceTagConf,
        target: this.form.connTargetTagConf,
      };
      this.form.checkDbSource;
      this.form.checkDbTarget;
      console.log(this.form.connSource);
      console.log(this.form.connTarget);

      schema.init(mysql, conn_config, function (err) {
        if (err) {
          // Utils.colorPrint("Schema init error:" + err.stack, Utils.STYLES.red);

          console.log("Schema init error:" + err.stack);
          // process.exit(1);
        }
        var sql = "";

        // 已删除表
        var deletedTables = schema.getDeletedTables();
        for (var i = 0; i < deletedTables.length; ++i) {
          sql += util.format(
            "DROP TABLE `%s`.`%s`;",
            schema.proInfo.getDbName(),
            deletedTables[i]
          );
        }
        if (deletedTables.length !== 0) {
          console.log(
            "The deleted table names are: " + deletedTables.join(", ")
          );
          // Utils.colorPrint(
          //   "The deleted table names are: " + deletedTables.join(", "),
          //   Utils.STYLES.yellow
          // );
        }

        // 新建表
        var newTables = schema.getNewTables();
        for (var i = 0; i < newTables.length; ++i) {
          sql += "\n\n" + schema.devInfo.createTableSQL[newTables[i]] + ";";
        }
        if (newTables.length !== 0) {
          console.log("The new table names are: " + deletedTables.join(", "));

          // Utils.colorPrint(
          //   "The new table names are: " + deletedTables.join(", "),
          //   Utils.STYLES.yellow
          // );
        }

        // 修改表
        var modifiedTables = [];
        var mayModifiedTables = schema.getMayModifiedTables();
        for (var i = 0; i < mayModifiedTables.length; ++i) {
          var tableName = mayModifiedTables[i];
          var columnsName = schema.devInfo.getTableColumnNames(tableName);

          var newColumns = schema.getTableNewColumns(tableName);
          var deletedColumns = schema.getTableDeletedColumns(tableName);
          var mayModifiedColumns = schema.getTableMayModifiedColumns(tableName);

          // 删除字段
          var modifiedStringArray = [];
          for (var j = 0; j < deletedColumns.length; ++j) {
            modifiedStringArray.push(
              util.format("\n  DROP COLUMN `%s`", deletedColumns[j])
            );
          }

          // 新增字段
          for (var j = 0; j < newColumns.length; ++j) {
            var index = _.indexOf(columnsName, newColumns[j]);
            if (index === 0) {
              modifiedStringArray.push(
                util.format(
                  "\n  ADD COLUMN %s FIRST",
                  schema.devInfo.getColumnSQL(tableName, newColumns[j])
                )
              );
            } else {
              modifiedStringArray.push(
                util.format(
                  "\n  ADD COLUMN %s AFTER `%s`",
                  schema.devInfo.getColumnSQL(tableName, newColumns[j]),
                  columnsName[index - 1]
                )
              );
            }
          }

          // 修改字段
          for (var j = 0; j < mayModifiedColumns.length; ++j) {
            var devColumnSQL = schema.devInfo.getColumnSQL(
              tableName,
              mayModifiedColumns[j]
            );
            var proColumnSQL = schema.proInfo.getColumnSQL(
              tableName,
              mayModifiedColumns[j]
            );
            if (devColumnSQL !== proColumnSQL) {
              modifiedStringArray.push(
                util.format(
                  "\n  CHANGE COLUMN `%s` %s",
                  mayModifiedColumns[j],
                  devColumnSQL
                )
              );
            }
          }

          // 主键
          var devPrimarySQL = schema.devInfo.getPrimariesSQL(tableName);
          var proPrimarySQL = schema.proInfo.getPrimariesSQL(tableName);
          if (devPrimarySQL !== proPrimarySQL) {
            modifiedStringArray.push(
              util.format("\n  DROP PRIMARY KEY, ADD %s", devPrimarySQL)
            );
          }

          // 索引
          var deletedKeys = schema.getTableDeletedKeys(tableName);
          for (var j = 0; j < deletedKeys.length; ++j) {
            modifiedStringArray.push(
              util.format("\n  DROP KEY `%s`", deletedKeys[j])
            );
          }

          var newKeys = schema.getTableNewKeys(tableName);
          for (var j = 0; j < newKeys.length; ++j) {
            modifiedStringArray.push(
              util.format(
                "\n  ADD %s",
                schema.devInfo.getKeySQL(tableName, newKeys[j])
              )
            );
          }

          var mayModifiedKeys = schema.getTableMayModifiedKeys(tableName);
          for (var j = 0; j < mayModifiedKeys.length; ++j) {
            var devKeySQL = schema.devInfo.getKeySQL(
              tableName,
              mayModifiedKeys[j]
            );
            var proKeySQL = schema.proInfo.getKeySQL(
              tableName,
              mayModifiedKeys[j]
            );
            if (devKeySQL !== proKeySQL) {
              modifiedStringArray.push(
                util.format("\n  DROP KEY `%s`", mayModifiedKeys[j])
              );
              modifiedStringArray.push(util.format("\n  ADD %s", devKeySQL));
            }
          }

          // 设置
          var devEngineSQL =
            schema.devInfo.getTableEngineAndSettingSQL(tableName);
          var proEngineSQL =
            schema.proInfo.getTableEngineAndSettingSQL(tableName);
          if (devEngineSQL !== proEngineSQL) {
            modifiedStringArray.push(util.format("\n  %s", devEngineSQL));
          }

          if (modifiedStringArray.length !== 0) {
            modifiedTables.push(tableName);
            sql += util.format(
              "\n\nALTER TABLE `%s`.`%s`",
              schema.proInfo.getDbName(),
              tableName
            );
            sql += modifiedStringArray.join(",") + ";";
          }
        }
        if (modifiedTables.length !== 0) {
          console.log(
            "The altered table names are: " + modifiedTables.join(", ")
          );

          // Utils.colorPrint(
          //   "The altered table names are: " + modifiedTables.join(", "),
          //   Utils.STYLES.yellow
          // );
        }
        // that.form.sqlText=format(sql, { language: "mysql" })

        that.form.sqlTextShow = sql
          .replace(/[\r\n]/g, "<br>")
          .replace(/\n/, "<br>");
        console.log(that.form.sqlText);

        that.form.sqlText = sql
          .replace(/[\r\n]/g, " ")
          .replace(/\ +/g, " ")
          .replace(/\;\s+/, ";\n");

        schema.end();
      });
    },
  },
};
</script>
